{
 "cells": [
  {
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-09-11T07:52:48.340766Z",
     "start_time": "2025-09-11T07:52:48.332782Z"
    }
   },
   "cell_type": "markdown",
   "source": [
    "# 基础知识\n",
    "\n",
    "## Python简介\n",
    "\n",
    "### 什么是Python\n",
    "\n",
    "- Python是一门解释型、面向对象的高级编程语言。\n",
    "- Python是开源免费的、支持交互式、可跨平台移植的脚本语言。\n",
    "\n",
    "### Python 历史\n",
    "\n",
    "- Python 于20世纪90年代初，由荷兰人吉多·范罗苏姆 （Guido van Rossum）基于C语言开发。\n",
    "- 之所以选中 Python（大蟒蛇的意思）作为该编程语言的名字，是因为 Guido 是室内情景喜剧《蒙提.派森的飞行马戏团》（Monty Python's Flying Circus）的忠实观众。\n",
    "- 目前使用的 Python 版本主要有 Pyton 2.x 和 Python 3.x 两种，而后者并不完全兼容前者的语法。如果没有特殊的应用需求，建议使用 Python 3.x 。\n",
    "- 官方网站：http://www.python.org\n",
    "\n",
    "### Python 的特点\n",
    "\n",
    "- 优点：简单易学、免费开源、跨平台性、高层语言、面向对象、代码库丰富、胶水语言……\n",
    "- 缺点：运行速度慢、代码不能加密……\n",
    "\n",
    "扩展知识：编译型语言 vs 解释型语言\n",
    "\n",
    "- 编译型语言：将源代码在指定平台上一次性编译为目标代码，之后可以多次执行目标代码。语法错误可以在编译期被发现，每次修改后都需要重新编译，但执行速度较快。典型代表：C、C++、Java、C#等。\n",
    "- 解释型语言：源代码每次运行，都需要逐行解释然后执行。 语法错误在执行时被发现，每次修改后不需要重新编译，但执行速度较慢。典型代表：Python、JavaScript等。\n",
    "\n",
    "### Python应用领域\n",
    "\n",
    "- 主要应用领域：系统编程、图形界面开发、科学计算、文本处理、数据库编程、网络编程、Web开发、自动化运维、金融分析、多媒体应用、游戏开发、人工智能、网络爬虫……\n",
    "- 数据分析与数据可视化：NumPy、SciPy、Pandas、Matplotlib等可以让 Python 程序员编写科学计算程序，对数据进行清洗、去重、规格化和针对性的分析，从而完成科学计算、数据分析和数据可视化。\n",
    "- 人工智能：Python 在人工智能领域内的机器学习、神经网络、深度学习等方面都是主流的程序语言，得到广泛的支持和应用。\n",
    "- 网络应用：大数据行业获取数据的核心工具是网络爬虫，对于各种网络协议的支持很完善，Python 是编写网络爬虫和其它网络应用软件的主流编程语言， Scrapy 爬虫框架应用非常广泛。\n",
    "- Web开发：Python 有 Flask、Django、TurboGears、web2py 等优秀框架，方便开发各种 Web 应用。\n",
    "- 自动化运维：Python 可以方便的处理文本数据、CSV文件、Excel表格、JSON格式数据等各种类型的数据，也可以连接 SQLite、MySQL 等数据库管理数据。Python 脚本可以分析日志、安排定时任务及发送电子邮件。\n",
    "- 桌面软件：使用 PyQt、PySide、wxPython、PyGTK 等可以快速开发基于 Python 的桌面应用程序。\n",
    "- 游戏：Python 有 Pygame 等编写游戏的模块。很多游戏使用 C++ 编写图形显示等高性能模块，而使用 Python 编写游戏的逻辑引擎服务器。\n",
    "\n",
    "## 输入与输出\n",
    "\n",
    "### 第一个程序 —— print输出"
   ],
   "id": "4f8bdfc1b8dc0cad"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:53.400372Z",
     "start_time": "2025-10-24T04:49:53.385645Z"
    }
   },
   "cell_type": "code",
   "source": "print(\"Hello world!\")",
   "id": "8b9e58296d6ab363",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello world!\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- print()用来输出信息\n",
    "- 字符串：用一对引号包围起来的字符序列。一对引号，可以是一对单引号，也可以是一对双引号，但不可混用。\n",
    "\n",
    "### 欢迎程序 —— input输入\n"
   ],
   "id": "94552bf47e98604b"
  },
  {
   "metadata": {
    "jupyter": {
     "is_executing": true
    }
   },
   "cell_type": "code",
   "source": [
    "name = input(\"What's your name? \")\n",
    "print(\"Hello\", name)"
   ],
   "id": "89fade3ead5f665f",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- input() 首先给出提示信息，然后等待用户输入。输入的信息为字符串类型，保存在赋值号前的变量中。\n",
    "- print()函数会在输出的多个参数之间自动添加一个空格。例如：\n"
   ],
   "id": "6b3b378e177c1a31"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.079006500Z",
     "start_time": "2025-09-11T13:21:43.513402Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(\"Hello\", \"world\")"
   ],
   "id": "f3d6bb51ee13939e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello world\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- 对比：二个字符串可以用+连接在一起，此时不会在中间自动添加一个空格。如\"hello\"+\"world\" => \"helloworld\""
   ],
   "id": "c3ce6bd2f47dff32"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.080624Z",
     "start_time": "2025-10-21T11:10:26.408235Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 请同学们自己编写代码，进行验证\n",
    "print(\"Hello\" + \"world\")"
   ],
   "id": "5762b59728831663",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Helloworld\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## you-get\n",
    "### 例子：求圆的周长和面积\n",
    "\n",
    "- 输入圆的半径，计算圆的周长和面积并输出。\n",
    "- 输入：圆的半径 radius\n",
    "- 输出：圆的周长 perimeter 和面积 area\n",
    "- 提示：圆周率使用math.pi。圆的周长 $perimeter = 2 \\times \\pi \\times radius $，圆的面积 $area = \\pi \\times radius ^ 2 $\n",
    "\n",
    "- 输入输出示例：\n",
    "- 输入：\n",
    "```\n",
    "5\n",
    "```\n",
    "- 输出：\n",
    "```\n",
    "31.41592653589793\n",
    "78.53981633974483\n",
    "```"
   ],
   "id": "6f7ff500ad20b5c1"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.081708500Z",
     "start_time": "2025-10-20T01:36:22.591399Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import math\n",
    "\n",
    "radius = float(input(\"请输入圆的半径：\"))\n",
    "perimeter = 2 * radius * math.pi\n",
    "area = math.pi * radius ** 2\n",
    "print(perimeter)\n",
    "print(area1)"
   ],
   "id": "d67489d1a90d8e7a",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "31.41592653589793\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "name 'area1' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001B[31m---------------------------------------------------------------------------\u001B[39m",
      "\u001B[31mNameError\u001B[39m                                 Traceback (most recent call last)",
      "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[6]\u001B[39m\u001B[32m, line 7\u001B[39m\n\u001B[32m      5\u001B[39m area = math.pi * radius ** \u001B[32m2\u001B[39m\n\u001B[32m      6\u001B[39m \u001B[38;5;28mprint\u001B[39m(perimeter)\n\u001B[32m----> \u001B[39m\u001B[32m7\u001B[39m \u001B[38;5;28mprint\u001B[39m(\u001B[43marea1\u001B[49m)\n",
      "\u001B[31mNameError\u001B[39m: name 'area1' is not defined"
     ]
    }
   ],
   "execution_count": 6
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- input() 得到的输入总是字符串，如果输入了数字并计划后续参与运算，应该转换为数字类型。int()可以转换整数，float()可以转换浮点数，而eval()可以计算整个字符串表达式。\n",
    "\n",
    "### 例子：计算体质指数BMI\n",
    "- 体质指数（body mass index ，简称BMI）是评价18岁以上成人群体营养状况的指标，可由 体重（单位：千克）和 身高 （单位：米）计算出来。\n",
    "- BMI的计算公式为：$BMI = 体重 \\div 身高 ^2$\n",
    "- 输入：体重 weight（单位：千克）和身高 height（单位：米）\n",
    "- 输出：计算并输出 BMI 值。\n",
    "- 输入输出示例：\n",
    "- 输入：\n",
    "```\n",
    "60\n",
    "1.6\n",
    "```\n",
    "- 输出：\n",
    "```\n",
    "23.437499999999996\n",
    "```"
   ],
   "id": "40d83e4e813d3068"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### IPO\n",
    "\n",
    "- 输入 Input - 处理 Process - 输出 Output\n",
    "- 建议将程序分成三段，输入、处理、输出，这样条理清晰。\n",
    "\n",
    "### 输出语句print()函数\n",
    "\n",
    "- 可以输出一个或者多个对象，当输出多个对象时，对象之间要用逗号分隔。\n",
    "- 默认情况下，多个输出的对象之间，用一个空格分隔。可以用参数 sep 设置输出时对象之间的分隔符。\n",
    "- <font color='red'>python函数的位置参数和关键字参数</font>\n"
   ],
   "id": "9a11161e953d0dd6"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.083003600Z",
     "start_time": "2025-10-20T01:56:15.868115Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print('hello', 'world', '!')\n",
    "# hello world !\n",
    "print('hello', 'world', '!', sep='*', end='\\n')\n",
    "# hello*world*!\n",
    "print('hello', 'world', '!')\n",
    "# helloworld!"
   ],
   "id": "a19941d5d25e8ea1",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world !\n",
      "hello*world*!\n",
      "hello world !\n"
     ]
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- 默认情况下，每次输出以换行符结尾。可以用参数 end 设置输出以何字符结尾。\n",
    "- 参数 end 与 sep 的出现顺序没有要求，但是必须放在要显示的内容之后。\n",
    "- 单独一个print()没有任何参数，会输出一个空换行。"
   ],
   "id": "fba5cf269fab8651"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 变量与赋值\n",
    "\n",
    "### 变量\n",
    "\n",
    "- 变量是计算机语言中能储存计算结果或能表示值的抽象概念。变量可以通过变量名访问。\n",
    "\n",
    "### 创建变量\n",
    "\n",
    "- 赋值语句：`变量名 = 变量值`\n",
    "- = 叫做赋值运算符。**注意，它并不是数学中的等号！**\n",
    "- 变量名：可以理解为是门牌号码（引用而不是存储）\n",
    "- 例如:"
   ],
   "id": "98f18d31cf5b1173"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "name = \"Larry“\n",
    "y = 1\n",
    "radius = 1.0\n",
    "x = 5 * (3 / 2) + 3 * 2\n",
    "x = y + 1\n",
    "area = radius * radius * 3.14159"
   ],
   "id": "6ba4de36cdceb549"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 赋值的等号不是数学的等号\n",
    "\n",
    "- 请不要把赋值语句的等号等同于数学的等号。比如下面的代码："
   ],
   "id": "c67d760fa903f427"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    " x = 10\n",
    "x = x + 2"
   ],
   "id": "a1db2202d1452c9e"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- 如果从数学上理解 `x = x + 2` 那无论如何是不成立的。在程序中，处理过程是：\n",
    "\n",
    "  - 赋值语句先计算右侧的表达式 x+2，得到结果 12\n",
    "  - 再将结果 12 赋给变量 x\n",
    "  - 由于 x 之前的值是 10，重新赋值后，x的值变成 12。\n",
    "- 而且，赋值号的左边只能是变量。比如下面的代码是错误的："
   ],
   "id": "6eb035d757120c06"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    " 1 = x\n",
    "2 * x = 3 + y"
   ],
   "id": "d61586874cf7dd3d"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 连续赋值"
   ],
   "id": "fea77dbcc3d0c1dd"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "i = j = k = 1"
   ],
   "id": "afdc35de9b2a462f"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "等价于："
   ],
   "id": "3d80f02a655a9f9b"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "k = 1\n",
    "j = k\n",
    "i = j"
   ],
   "id": "905443dac5173a63"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 同时赋值"
   ],
   "id": "76ebaf3c56fadf07"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "x, y = 2, 3\n",
    "x, y = x + y, x * y"
   ],
   "id": "924355c1aeb39424"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 交换值"
   ],
   "id": "eea4d1adc147e50f"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "x = 2\n",
    "y = 3\n",
    "t = x\n",
    "x = y\n",
    "y = t"
   ],
   "id": "b9b1a15077283bea"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "由于Python支持同时赋值，上述过程可以简化为："
   ],
   "id": "f2a0d7255219b1ad"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "x, y = y, x"
   ],
   "id": "7d5fbe2694b1b548"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 变量命名\n",
    "\n",
    "- 标识符：作为变量、函数等名字的有效字符串集合\n",
    "- 关键字（keyword）：Python语言保留使用的标识符，又称保留字，不能用于其它用途（如变量名）。使用下面的方法可以列出关键字。"
   ],
   "id": "c39059db09adf6b4"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.124774900Z",
     "start_time": "2025-09-11T14:05:56.133960Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import keyword\n",
    "\n",
    "print(keyword.kwlist)"
   ],
   "id": "b5527c53074039a8",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']\n"
     ]
    }
   ],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- 变量名只能含有数字, 字母以及下划线\n",
    "- 变量名不能以数字开头\n",
    "- 选择具有描述性的名字，做到望名知意！例如”score”而不是”s”。\n",
    "- 风格保持一致，常见的变量命名风格有：\n",
    "\n",
    "  - high_score（下划线命名法）\n",
    "  - highScore（小驼峰命名法）\n",
    "  - HighScore（大驼峰命名法）\n",
    "- 遵循语言习惯\n",
    "\n",
    "  - Python推荐下划线命名法，也有一些人习惯使用小驼峰命名法（可能是受 Java 语言影响）。这两种风格都可以，但是建议不要在一个程序中混用。\n",
    "  - 大驼峰命名法一般不得用于变量命名（大驼峰命名法另有用途，如类名或为异常命名）\n",
    "  - 一般不得使用全大写字母做变量名（如：NUMBER_OF_THE_RESULT），这种命名一般代表常量（即值不会发生变化的变量，虽然 Python 并没有语法对此加以限制）\n",
    "  - 不用下划线开头或结尾（下划线开头或结尾的变量往往有特殊的用途）\n",
    "  - 变量名不要太长，最好在15个字符以内\n",
    "  - 除特殊情况外（如循环控制变量习惯用i），一般不得使用单字母作为变量名\n",
    "  - 一般使用英文单词命名，汉语环境中很难对应翻译为英文可以用拼音，但是不允许英拼混用（错误示例：RunYear代表闰年），更不允许使用拼音首字母缩写（错误示例：ncwssmys你猜我是什么意思）\n",
    "  - 不允许在变量名中出现汉字，尽管Python看起来也能正确处理。\n",
    "\n",
    "## 数据类型、运算符与表达式\n",
    "\n",
    "### 数据类型\n",
    "\n",
    "- <font color='blue'>计算机处理的数据，是要区分数据类型的。</font>\n",
    "- Python 中数据类型，主要分为基本数据类型、内置容器类型和自定义类型\n",
    "  - 基本数据类型：整数int(integer)、浮点数float、复数complex、布尔型bool(boolean)等\n",
    "  - 内置容器类型：字符串型str(string)、元组tuple、列表list、字典dict(dictionary)、集合set等\n",
    "  - 自定义类型：自定义类、第三方类等\n",
    "- 本章主要介绍整数和浮点数类型，其它类型的数据，将在后续章节中展开介绍。\n",
    "\n",
    "### 运算符\n",
    "\n",
    "- 运算符用于执行程序代码运算，会针对一个及以上操作数项目来进行运算。\n",
    "- 按操作数个数分，可分为一元运算符、二元运算符等。\n",
    "- 大部分运算符为二元运算符，如a+b，+即为加法运算符，它的操作数有二个：a和b 。一般来说，二元运算符位于二个操作数之间。\n",
    "- 部分运算符为一元运算符，如-a，-为取负运算符，它只有a这一个操作数，意为负的a，如果a为5，则-a为-5，而如果a为-3，则-a为3。一般来说，一元运算符位于操作数前面。\n",
    "- 按作用来分，Python 中的运算符包括算术运算符、比较运算符、逻辑运算符、赋值运算符、位运算符、成员运算符和身份运算符等。\n",
    "- 本章主要介绍用于数字型数据的算术运算和比较运算，也会介绍逻辑运算、赋值运算的使用，部分其它类型的运算，将在后续章节中展开介绍。\n",
    "\n",
    "### 表达式\n",
    "\n",
    "- 表达式一般由运算符和操作数（操作对象）组成。例如，1+2，+为二元运算符，1和2是操作数。\n",
    "- 仅操作数也可以构成表达式。如：1\n",
    "\n",
    "## 数字类型和运算\n",
    "\n",
    "### 数字型\n",
    "\n",
    "- 整数：没有小数部分的数字，例如：1, 27, -100, 0 . Python中的整数即数学中的整数，理论上 Python 可以处理任意大小的整数，包括正整数、零和负整数。\n",
    "- 浮点数：带有小数点的数字，例如：2.376, -99.1, 1.0 . Python中的浮点数并不等价于数学中的小数，Python 并不能处理所有的小数。\n",
    "- 复数：形如 a+bj 的数字，例如：2+3j\n",
    "\n",
    "#### 关于进制\n",
    "\n",
    "- 人类社会习惯使用十进制，大概是因为人一般有10根手指，在远古运算时天然形成“逢十进一”的习惯。\n",
    "\n",
    "- 计算机中大量使用的光、电、磁，都只有二种状态（光或电流的有无、正负电荷、南北磁极），所以计算机天然形成了“逢二进一”的习惯，即二进制。\n",
    "\n",
    "- 用二进制表示的数字太长，人类阅读不便，从而产生了八进制和十六进制。其中十六进制需要借用\"A~F\"代表10～15。\n",
    "\n",
    "  | 进制     | 前缀 | 转换函数 | 示例                 |\n",
    "  | -------- | ---- | -------- | -------------------- |\n",
    "  | 十进制   | 无   | int()    | int(0x61) -> 97      |\n",
    "  | 二进制   | 0b   | bin()    | bin(97) -> 0b1100001 |\n",
    "  | 八进制   | 0o   | oct()    | oct(97) -> 0o141     |\n",
    "  | 十六进制 | 0x   | hex()    | hex(97) -> 0x61      |\n",
    "\n",
    "#### 关于浮点数的说明\n",
    "\n",
    "- 浮点数对应数学上的小数，但是 Python 并不能处理数学上所有的小数。\n",
    "- 浮点数大小有限制。不能处理绝对值过大或过小的小数。绝对值最大的浮点数为 1.7976931348623157e+308 （科学计数法，记为aen或aEn，其中a代表尾数，n代表指数，e或E是固定的字符，作为尾数和指数的分隔，含义为a 乘以10的n次方），绝对值最小的浮点数为 2.2250738585072014e-308。\n",
    "- 浮点数精度有限制。浮点数只有15位有效数字，超长的部分没有意义。\n",
    "- 之所以称为浮点数，是因为按照科学记数法表示时，一个浮点数的小数点位置是可变的，比如，1.23乘以10的9次方 和 12.3乘以10的8次方 是完全相等的。浮点数可以用数学写法，如1.23，3.14，-9.01，等等。但是对于很大或很小的浮点数，就必须用科学计数法表示，把10用e替代，`1.23*10**9`就是1.23e9，或者12.3e8，0.000012可以写成1.2e-5，等等。\n",
    "- 整数和浮点数在计算机内部存储的方式是不同的，整数运算永远是精确的，而浮点数运算则可能会有误差。\n",
    "\n",
    "  > 著名的 0.1+0.2不等于0.3问题\n",
    "  >\n",
    "  > 计算机能正确的计算整数，如1+2=3，但是，如果用计算机计算0.1+0.2，却得不到0.3！\n",
    "  >\n",
    "  >> 0.1 + 0.2 = 0.30000000000000004\n",
    "  >>\n",
    "  >\n",
    "  > 这并不是 Python 出错了，而是大多数计算机程序都会得到的结果。为此专门还有人建立了一个网站，叫 http://0.30000000000000004.com (3和4之间有15个0)\n",
    "  >\n",
    "- 同样的，二个浮点数比较是否相等，是很容易出问题的。如下例，如果判断a是否等于b，那结果是不等于，但是如果判断a减b的绝对值是否小于 eps，如果小于eps，就可以近似的认为a等于b 。其中eps的值由实际应用需要而定。\n"
   ],
   "id": "ecabedae3222da4a"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.128036400Z",
     "start_time": "2025-09-11T14:19:04.955884Z"
    }
   },
   "cell_type": "code",
   "source": [
    "a = 0.1 + 0.2\n",
    "b = 0.3\n",
    "eps = 0.000001\n",
    "print(a == b)  # a等于b吗？False\n",
    "print(abs(a - b) < eps)  # a近似等于b吗？True"
   ],
   "id": "90a90d2f3e016922",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "execution_count": 9
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- 解决这类问题的方法，一种方法是尽量使用整数，如处理与金钱相关的数值时，以分为单位。另一种方法是使用decimal模块。"
   ],
   "id": "f7847e04d1d8144d"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "from decimal import Decimal\n",
    "\n",
    "a = Decimal('0.1')\n",
    "b = Decimal('0.2')\n",
    "print(a + b)  # 会输出 0.3"
   ],
   "id": "fbdbfdedecd7bb1c"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 算术运算\n",
    "\n",
    "#### 算术运算符\n",
    "\n",
    "- 用于数字的算术运算符，与数学中的运算基本一致，只有除法分成了三种运算符。\n",
    "- Python 不认识×号，所以乘法运算用*代替。\n",
    "- Python 不认识÷号，所以除法运算用/代替。\n",
    "\n",
    "| 运算符 | 描述                                                            | 举例                   |\n",
    "| :----- | :-------------------------------------------------------------- | :--------------------- |\n",
    "| +      | 一元运算符，一元加，+a 即得到该操作数本身不变                   | 如a=-10，则+a仍然是-10 |\n",
    "| -      | 一元运算符，一元减，-a 即得到变换该操作数的符号的数             | 如a=-10，则-a是10      |\n",
    "| +      | 二元运算符，加法，a+b 两个对象相加                              | 10 + 20 结果 30        |\n",
    "| -      | 二元运算符，减法，a-b 两个对象相减                              | 10 - 20 结果 -10       |\n",
    "| *      | 二元运算符，乘法，a*b 两个对象相乘。                            | 10 * 20 结果 200       |\n",
    "| /      | 二元运算符，算术除法（truediv），a/b 结果总是浮点数。           | 15 / 2 结果 7.5        |\n",
    "| //     | 二元运算符，地板除法（floordiv），a//b 返回除法的商。           | 10 // 3 结果是 3       |\n",
    "| %      | 二元运算符，取模运算（mod），又叫取余运算，a%b 返回除法的余数。 | 10 % 3 结果是 1        |\n",
    "| **     | 二元运算符，乘方运算，又叫幂运算，a**b 返回a的b次幂             | 2 ** 3 结果是 8        |\n",
    "\n",
    "#### 算术运算符的优先级\n",
    "\n",
    "- 与数学中的先乘除、后加减的常识相同，用于数字的算术运算符的优先级为（从高到低）：\n",
    "  - 幂运算符\n",
    "  - 一元运算符：一元加、一元减\n",
    "  - 乘除运算符：乘法、算术除法、地板除法、取模（取余）\n",
    "  - 加减运算符：二元加、二元减\n",
    "- 同样的，可以使用小括号来调整运算的优先级。注意与数学中不同，调整运算优先级时永远使用小括号，无论有多少级。中括号和大括号在Python中另有用途。\n",
    "\n",
    "#### 关于除法的说明\n",
    "\n",
    "- 算术除法（truediv），算术除法会得到较精确的结果，结果总是浮点数，即使结果应为整数，也要在其后加上.0转为浮点数的形式。如："
   ],
   "id": "1d3b79088f04049f"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.136295400Z",
     "start_time": "2025-09-11T14:22:00.263198Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(5 / 2)  # 2.5\n",
    "print(6 / 2)  # 3.0\n",
    "print(10 / 3)  # 3.3333333333333335"
   ],
   "id": "409c3c95401d96cd",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.5\n",
      "3.0\n",
      "3.3333333333333335\n"
     ]
    }
   ],
   "execution_count": 10
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- 地板数：指不大于此数的最大整数。如："
   ],
   "id": "5062f7024943e3"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.138296400Z",
     "start_time": "2025-09-11T14:22:46.296206Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import math\n",
    "\n",
    "print(math.floor(-3.5))  # -4\n",
    "print(math.floor(-3))  # -3\n",
    "print(math.floor(3.5))  # 3\n",
    "print(math.floor(3))  # 3"
   ],
   "id": "924866f012fca58c",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-4\n",
      "-3\n",
      "3\n",
      "3\n"
     ]
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- 地板除法（floor），地板除法得到算术除法结果的地板数，即除法的商。如果两个操作数中有浮点数，则结果以浮点数形式表示，即加上.0"
   ],
   "id": "c5a7b088f008a1a8"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.140296700Z",
     "start_time": "2025-09-11T14:38:31.117357Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(10 // 3)  # 3\n",
    "print(9 // 3)  # 3\n",
    "print(-9 // 3)  # -3\n",
    "print(-10 // 3)  # -4\n",
    "print(10 // 3.5)  # 2.0\n",
    "print(-10 // 3.5)  # -3.0"
   ],
   "id": "927bef4a1701c37e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "3\n",
      "-3\n",
      "-4\n",
      "2.0\n",
      "-3.0\n"
     ]
    }
   ],
   "execution_count": 12
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- 取余（取模）运算，得到除法的余数。具体的公式如下：设 x // y = z，则 x % y = x – (y*z)"
   ],
   "id": "7e0a649b4579d7c3"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.141296500Z",
     "start_time": "2025-09-11T14:38:56.245620Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(10 % 3)  # 1\n",
    "print(-10 % 3)  # 2\n",
    "print(-10 % -3)  # -1\n",
    "print(-10 % -3.5)  # -3.0"
   ],
   "id": "1aa2abe07e83001a",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "-1\n",
      "-3.0\n"
     ]
    }
   ],
   "execution_count": 13
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 例子：求n天后是周几\n",
    "\n",
    "- 如果已知今天是周四，求n天后是周几？\n",
    "- 用1代表周一，2代表周二，……，6代表周六，0代表周日"
   ],
   "id": "a057b56aed730060"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "n = int(input())\n",
    "print((4 + n) % 7)"
   ],
   "id": "32b3fc678633239a"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 例子：反转输出一个四位整数\n",
    "\n",
    "- 输入：一个四位（1000～9999之间）整数\n",
    "- 输出：反转各位数字后显示。\n",
    "- 提示：反转后如果最高位为0的，不需要显示最高位的0。\n",
    "\n",
    "| 示例 | 输入 | 输出 |\n",
    "| ---- | ---- | ---- |\n",
    "| 1    | 3125 | 5213 |\n",
    "| 2    | 8670 | 768  |"
   ],
   "id": "34b4fc9127195bbd"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.147295700Z",
     "start_time": "2025-09-11T14:41:14.965108Z"
    }
   },
   "cell_type": "code",
   "source": [
    "n = int(input())\n",
    "a = n // 1000  # 千位\n",
    "b = n // 100 % 10  # 百位\n",
    "c = n // 10 % 10  # 十位\n",
    "d = n % 10  # 个位\n",
    "m = d * 1000 + c * 100 + b * 10 + a\n",
    "print(m)"
   ],
   "id": "2eef7c2ec2bc1464",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2543\n"
     ]
    }
   ],
   "execution_count": 16
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 常用内置数学函数\n",
    "\n",
    "| 函数           | 描述                                                           | 举例                |\n",
    "| -------------- | -------------------------------------------------------------- | ------------------- |\n",
    "| abs(x)         | 返回x的绝对值                                                  | abs(-2)=2           |\n",
    "| max(x1,x2,...) | 返回x1,x2,...的最大值                                          | max(1,5,2)=5        |\n",
    "| min(x1,x2,...) | 返回x1,x2,...的最小值                                          | min(1,5,2)=1        |\n",
    "| pow(a,b)       | 返回a的b次方值，等价于a**b                                     | pow(2,3)=8          |\n",
    "| round(x)       | 返回与x最接近的整数。如果x与两个整数接近程度相同，则返回偶数值 | round(4.5)=4        |\n",
    "| round(x,n)     | 保留浮点数点后n位小数的浮点数值                                | round(5.466,2)=5.47 |\n",
    "\n",
    "- round(x)函数与四舍五入的比较。一般情况下round(x)相当于数学上的将x四舍五入到整数，但是当x的小数部分恰好为.5时，即x与上下两个整数接近程度相同，则返回两个整数中的偶数值。如round(3.5)=4; round(4.5)=4; round(5.5)=6; round(-2.5)=-2; round(-3.5)=-4\n",
    "- 对比：int(x)是将x的小数部分直接截断丢弃。如 int(4.5)=4; int(-3.5)=-3\n",
    "- 当x大于等于0时，可以使用 int(x+0.5) 得到数学上的将x四舍五入到整数的结果。如 int(3.5+0.5)=4; int(4.5+0.5)=5.\n",
    "- 当x小于0时，可以使用 int(x-0.5) 得到数学上的将x四舍五入到整数的结果。如：int(-3.5-0.5)=-4; int(-4.5-0.5)=5.\n",
    "- 上述二种情况，可以合并成一个表达式：int(x+0.5) if x>=0 else int(x-0.5)\n",
    "- 使用round(x,n)时，如果n>0，代表保留小数点后n位数字，如果n<0，则代表向小数点前保留-n位数字，默认n=0为保留到整数。如：round(1234.5678,2)=1234.57; round(1234.5678,-2)=1200.0\n",
    "- 由于浮点数的不精确性，当使用round(x,n)函数的参数n>0时，遇到被保留位后一位是5并且之后没有更多数字时，所得结果往往不可预测。这个问题与0.1+0.2!=0.3一样，都是浮点数在计算机中以二进制小数保存有关。如：round(1.235,2)=1.24; round(1.335,2)=1.33\n",
    "\n",
    "### 常用math库数学函数\n",
    "\n",
    "| 函数/常量        | 描述                                   | 举例                                   |\n",
    "| ---------------- | -------------------------------------- | -------------------------------------- |\n",
    "| math.pi          | 圆周率PI常数                           | math.pi=3.141592653589793              |\n",
    "| math.e           | 自然对数的底数e常数                    | math.e=2.718281828459045               |\n",
    "| math.fabs(x)     | 将x看作一个浮点数，返回它的绝对值      | math.fabs(-2)=2.0                      |\n",
    "| math.ceil(x)     | x向上取最近的整数，即不小于x的最小整数 | math.ceil(2.1)=3; math.ceil(-2.1)=-2   |\n",
    "| math.floor(x)    | x向下取最近的整数，即不大于x的最大整数 | math.floor(2.1)=2; math.floor(-2.1)=-3 |\n",
    "| math.exp(x)      | 常数e的x次方值                         | math.exp(1)=2.718281828459045          |\n",
    "| math.log(x)      | x的自然对数，即x以常数e为底数的对数值  | math.log(math.e)=1.0                   |\n",
    "| math.log(x,base) | x以base为底数的对数值                  | math.log(100,10)=2.0                   |\n",
    "| math.sqrt(x)     | x的平方根值                            | math.sqrt(4)=2.0                       |\n",
    "| math.sin(x)      | x的正弦函数值，x为弧度值               | math.sin(math.pi/2)=1.0                |\n",
    "| math.asin(x)     | x的反正弦函数值，结果为弧度值          | math.asin(1.0)=1.5707963267948966      |\n",
    "| math.cos(x)      | x的余弦函数值，x为弧度值               | math.cos(math.pi)=-1.0                 |\n",
    "| math.acos(x)     | x的反余弦函数值，结果为弧度值          | math.acos(1.0)=0.0                     |\n",
    "| math.tan(x)      | x的正切函数值，x为弧度值               | math.tan(0.0)=0.0                      |\n",
    "| math.atan(x)     | x的反正弦函数值，结果为弧度值          | math.atan(0.0)=0.0                     |\n",
    "| math.degrees(x)  | 将弧度值转换为角度值                   | math.degrees(math.pi)=180.0            |\n",
    "| math.radians(x)  | 将角度值转换为弧度值                   | math.radians(90)=1.5707963267948966    |\n",
    "\n",
    "### 数字类型转换\n",
    "\n",
    "#### 整数与浮点数相互类型转换\n",
    "\n",
    "- 浮点数转整数：int(x)，当x为浮点数时，将x的小数部分直接截断丢弃转为整数。如：int(4.5)=4; int(-3.5)=-3\n",
    "- 整数转浮点数：float(x)，当x为整数时，在x的后面补上.0转为浮点数。如：float(4)=4.0\n",
    "\n",
    "#### 浮点数转换为整数的几个函数的比较\n",
    "\n",
    "- int(x)：当x为浮点数时，将x的小数部分直接截断丢弃转为整数。\n",
    "- math.floor(x)：x向下取最近的整数，即不大于x的最大整数。\n",
    "- math.ceil(x)：x向上取最近的整数，即不小于x的最小整数。\n",
    "- round(x)：返回与x最接近的整数。如果x与两个整数接近程度相同，则返回偶数值。\n",
    "- int(x+0.5) if x>=0 else int(x-0.5)：返回数学上将x四舍五入到整数的值。\n",
    "\n",
    "### 比较运算\n",
    "\n",
    "- 比较运算的结果为布尔值，又叫逻辑值，只有两个值：True 和 False\n",
    "- 注意有二个符号的运算符是一个整体，其中的二个符号中间不可插入空格\n",
    "- 注意 `==`相当于数学上的等于号，而=是赋值号，与 `==`完全不同。\n",
    "\n",
    "| 运算符 | 描述                                              | 举例          |\n",
    "| ------ | ------------------------------------------------- | ------------- |\n",
    "| ==     | 等于，a==b，当a等于b时为True，否则为False         | 10==20为False |\n",
    "| !=     | 不等于，a!=b，当a不等于b时为True，否则为False     | 10!=20为True  |\n",
    "| <      | 小于，a<b，当a小于b时为True，否则为False          | 10<20为True   |\n",
    "| <=     | 小于等于，a<=b，当a小于等于b时为True，否则为False | 10<=20为True  |\n",
    "| >      | 大于，a>b，当a大于b时为True，否则为False          | 10>20为False  |\n",
    "| >=     | 大于等于，a>=b，当a大于等于b时为True，否则为False | 10>=20为False |\n",
    "\n",
    "### 例子：显示当前时间\n",
    "\n",
    "- 说明：time.time() 获得现在距离 Unix Epoch（1970-01-01 00:00:00 UTC）所经过的时间，整数部分单位为秒，小数部分代表毫秒。"
   ],
   "id": "d9cf9d8c21a68cc5"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.149297500Z",
     "start_time": "2025-10-14T03:40:48.434298Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import time\n",
    "\n",
    "currentTime = time.time()  # Get current time\n",
    "\n",
    "# Obtain the total seconds since midnight, Jan 1, 1970\n",
    "totalSeconds = int(currentTime)\n",
    "\n",
    "# Get the current second\n",
    "currentSecond = totalSeconds % 60\n",
    "\n",
    "# Obtain the total minutes\n",
    "totalMinutes = totalSeconds // 60\n",
    "\n",
    "# Compute the current minute in the hour\n",
    "currentMinute = totalMinutes % 60\n",
    "\n",
    "# Obtain the total hours\n",
    "totalHours = totalMinutes // 60\n",
    "\n",
    "# Compute the current hour\n",
    "currentHour = totalHours % 24\n",
    "\n",
    "# Display results\n",
    "print(\"Current time is \" + str(currentHour) + \":\"\n",
    "      + str(currentMinute) + \":\" + str(currentSecond) + \" GMT\")"
   ],
   "id": "2bd89c31c57a4c68",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Current time is 3:40:48 GMT\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 例子：房贷计算器\n",
    "\n",
    "- 输入：贷款年利率、贷款年限、总贷款额\n",
    "- 输出：月供、总还款额\n",
    "- 设每月还款额相同。计算公式如下：\n",
    "\n",
    "```\n",
    "月利率 = 年利率 / 12\n",
    "月供 = 总贷款额 * 月利率 / (1 - 1/(1+月利率)**(贷款年限*12) )\n",
    "总还款额 = 月供 * 贷款年限 * 12\n",
    "```\n"
   ],
   "id": "75204194d13d692f"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-25T01:52:31.416855Z",
     "start_time": "2025-10-25T01:52:31.362438Z"
    }
   },
   "cell_type": "code",
   "source": [
    "b = 2\n",
    "c = a + b\n",
    "print(c)"
   ],
   "id": "7a0b17c7a4ca8877",
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<string>, line 1)",
     "output_type": "error",
     "traceback": [
      "Traceback \u001B[36m(most recent call last)\u001B[39m:\n",
      "  File \u001B[92mD:\\SyncWorkspace\\Python\\Lecture2025\\Lesson2\\.venv\\Lib\\site-packages\\IPython\\core\\interactiveshell.py:3699\u001B[39m in \u001B[95mrun_code\u001B[39m\n    exec(code_obj, self.user_global_ns, self.user_ns)\n",
      "\u001B[36m  \u001B[39m\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[1]\u001B[39m\u001B[32m, line 1\u001B[39m\n\u001B[31m    \u001B[39m\u001B[31meval(\"a = 1\")\u001B[39m\n",
      "  \u001B[36mFile \u001B[39m\u001B[32m<string>:1\u001B[39m\n\u001B[31m    \u001B[39m\u001B[31ma = 1\u001B[39m\n      ^\n\u001B[31mSyntaxError\u001B[39m\u001B[31m:\u001B[39m invalid syntax\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.150297900Z",
     "start_time": "2025-09-11T14:47:01.735939Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# Enter yearly interest rate\n",
    "annualInterestRate = eval(input(\n",
    "    \"Enter annual interest rate, e.g., 8.25: \"))\n",
    "monthlyInterestRate = annualInterestRate / 1200\n",
    "\n",
    "# Enter number of years\n",
    "numberOfYears = eval(input(\n",
    "    \"Enter number of years as an integer, e.g., 5: \"))\n",
    "\n",
    "# Enter loan amount\n",
    "loanAmount = eval(input(\"Enter loan amount, e.g., 120000.95: \"))\n",
    "\n",
    "# Calculate payment\n",
    "monthlyPayment = loanAmount * monthlyInterestRate / (1\n",
    "                                                     - 1 / (1 + monthlyInterestRate) ** (numberOfYears * 12))\n",
    "totalPayment = monthlyPayment * numberOfYears * 12\n",
    "\n",
    "# Display results\n",
    "print(\"The monthly payment is \" +\n",
    "      str(int(monthlyPayment * 100) / 100))\n",
    "print(\"The total payment is \" + str(int(totalPayment * 100) / 100))"
   ],
   "id": "bae17b5d9e746ce7",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The monthly payment is 612.48\n",
      "The total payment is 146995.48\n"
     ]
    }
   ],
   "execution_count": 18
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 例子：计算二点间距离"
   ],
   "id": "330a4073f0a96533"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "# Enter the first point with two double values\n",
    "x1, y1 = eval(input(\"Enter x1 and y1: \"))\n",
    "\n",
    "# Enter the second point with two double values\n",
    "x2, y2 = eval(input(\"Enter x2 and y2: \"))\n",
    "\n",
    "# Compute the distance\n",
    "distance = ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) ** 0.5\n",
    "\n",
    "print(\"The distance between the two points is\", distance)"
   ],
   "id": "d5d015eb9f77ca13"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 例子：计算三角形内角\n",
    "\n",
    "- 输入三角形三个顶点的坐标 (x1,y1), (x2,y2), (x3,y3)\n",
    "- 可以求出三角形三边边长 a,b,c\n",
    "- 由边长a, b, c，可以求得三个内角A, B, C"
   ],
   "id": "68c0a00d74f91852"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "import math\n",
    "\n",
    "x1, y1, x2, y2, x3, y3 = eval(input(\"Enter three points: \"))\n",
    "\n",
    "a = math.sqrt((x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3))\n",
    "b = math.sqrt((x1 - x3) * (x1 - x3) + (y1 - y3) * (y1 - y3))\n",
    "c = math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))\n",
    "\n",
    "A = math.degrees(math.acos((a * a - b * b - c * c) / (-2 * b * c)))\n",
    "B = math.degrees(math.acos((b * b - a * a - c * c) / (-2 * a * c)))\n",
    "C = math.degrees(math.acos((c * c - b * b - a * a) / (-2 * a * b)))\n",
    "\n",
    "print(\"The three angles are \", round(A * 100) / 100.0,\n",
    "      round(B * 100) / 100.0, round(C * 100) / 100.0)"
   ],
   "id": "ac3e3a4c2de2be7b"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 字符类型\n",
    "\n",
    "* 计算机只认识0和1，不认识人类语言中的字符，所以要把字符进行编码后，计算机才可以使用字符。\n",
    "* Python 没有独立的字符类型，它并不区分字符和字符串，即使只是一个字符，也被当做字符串处理。\n",
    "\n",
    "### 字符编码\n",
    "\n",
    "- 最早的时候，计算机只能处理英文字符、数字和常用标点。编码字符集叫ASCII。ASCII编码共收录了 128 个字符，包含了基本的英文字母（包括大小写）、数字（也就是 1234567890）、标点符号（,.!等）、特殊符号（@#$%^&等）以及一些具有控制功能的字符（往往不会显示出来）。\n",
    "- Python3 缺省使用 UTF-8 编码。ASCII编码中的包含的字符，在 ASCII 与 UTF-8 中编码保持一致。UTF-8 编码使得 Python 很容易处理包括中文在内的多国语言文字。\n",
    "\n",
    "### 常用ASCII码\n",
    "\n",
    "| 编码 | 字符 |  | 编码 | 字符 |  | 编码 | 字符 |\n",
    "| :-: | :-: | :-: | ---- | :-: | :-: | --- | :-: |\n",
    "| 48 | 0 |  \\|  | 65 | A | \\| | 97 | a |\n",
    "| 49 | 1 | \\| | 66 | B | \\| | 98 | b |\n",
    "| 50 | 2 | \\| | 67 | C | \\| | 99 | c |\n",
    "| …… | …… | \\| | …… | …… | \\| | …… | …… |\n",
    "| 55 | 7 | \\| | 88 | X | \\| | 120 | x |\n",
    "| 56 | 8 | \\| | 89 | Y | \\| | 121 | y |\n",
    "| 57 | 9 | \\| | 90 | Z | \\| | 122 | z |\n",
    "\n",
    "### 字符与编码的转换\n",
    "\n",
    "- 使用ord(char)可以得到char字符的编码。\n",
    "- 使用chr(number)可以得到编码为number的字符。"
   ],
   "id": "a013156c03c902c"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.164650Z",
     "start_time": "2025-09-11T14:50:58.924323Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(ord('a'))\n",
    "print(ord('中'))\n",
    "print(chr(97))\n",
    "print(chr(22269))"
   ],
   "id": "90989092de6aae06",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "97\n",
      "20013\n",
      "a\n",
      "国\n"
     ]
    }
   ],
   "execution_count": 21
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- 字符比较大小的依据是它的编码，编码越大，字符在比较时就越大。"
   ],
   "id": "608080dfbd9f86a3"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.166285100Z",
     "start_time": "2025-09-11T14:52:10.487909Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(ord('A'))\n",
    "print(ord('a'))\n",
    "print('A' < 'a')"
   ],
   "id": "112d173fe27c5dd1",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "65\n",
      "97\n",
      "True\n"
     ]
    }
   ],
   "execution_count": 22
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 区分数字与字符\n",
    "\n",
    "- 计算机中数字类型与字符类型是严格区别的二种数据类型。其中容易给人造成困扰的字符中的数字字符。\n",
    "- 数字类型是可以进行数学运算的，比如 `1+2=3` ，这里面的 1、2、3 都是数字，可以进行数学运算。\n",
    "- 字符中的数字字符，如 '1'、'2'、'3'，本质上也是字符，与 'a'、'b'、'c' 一样，只能用来组成字符串，不能进行数学运算。比如 `'1'+'2'='12'` ，符合字符串相加代表连接的运算规则。\n",
    "\n",
    "### 数字与字符串类型转换\n",
    "\n",
    "#### 字符串转数字\n",
    "\n",
    "- int(x)：可将形为整数的字符串x转为整数，如int(\"45\")=45. 注意x不可为形为浮点数的字符串，如：int(\"4.5\")是会出错误的。\n",
    "- float(x)：可将形为浮点数或整数的字符串x转为浮点数，如：float(\"45\")=45.0; float(\"45.6\")=45.6\n",
    "- eval(x)：可以将字符串x视为一个表达式，计算其值。如：eval(\"1+2\")=3\n",
    "\n",
    "#### 数字转字符串\n",
    "\n",
    "- str(x)：可将整数或浮点数 x 转为字符串。当需要将一个字符串与数字相连接在一起时就需要使用此函数。如："
   ],
   "id": "b9f8488a0777a58e"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.167362600Z",
     "start_time": "2025-09-11T14:52:56.539453Z"
    }
   },
   "cell_type": "code",
   "source": [
    "a = 2\n",
    "b = 3\n",
    "s = \"The result of \" + str(a) + \"+\" + str(b) + \" is \" + str(a + b)\n",
    "print(s)"
   ],
   "id": "4db0eb28afd42701",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The result of 2+3 is 5\n"
     ]
    }
   ],
   "execution_count": 23
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 逻辑（布尔）运算\n",
    "\n",
    "### 逻辑（布尔）值\n",
    "\n",
    "- 二值逻辑：True、False\n",
    "\n",
    "### 其它类型的数值参与逻辑运算\n",
    "\n",
    "- 数字 0、0.0、0j 被视同 False，其它数字被视同 True\n",
    "- 空字符串、空元组、空列表、空字典、空集合，视同 False，上述数据类型的非空值视同 True\n",
    "- None被视同False\n",
    "- 可以使用 bool() 将其它数据类型转换为布尔类型值。"
   ],
   "id": "c8c5a2f81234c284"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.168459300Z",
     "start_time": "2025-09-11T14:54:37.274813Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(bool(0))  # False\n",
    "print(bool(1))  # True\n",
    "print(bool(''))  # False\n",
    "print(bool('False'))  # True"
   ],
   "id": "ce7b2d9b3a090343",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "execution_count": 25
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 逻辑（布尔）运算符\n",
    "\n",
    "- 三种运算：逻辑非 not、逻辑与 and、逻辑或 or\n",
    "- 运算优先级：not > and > or\n",
    "\n",
    "#### 逻辑非 not\n",
    "\n",
    "- 一元运算符，表示“相反”。not True即为False，not False即为True。\n",
    "- 逻辑非的真值表如下：\n",
    "\n",
    "| 操作数A | not A |\n",
    "| ------- | ----- |\n",
    "| True    | False |\n",
    "| False   | True  |\n",
    "\n",
    "- 逻辑非运算的返回结果：只有True和False二值"
   ],
   "id": "b90e2fb3e5a2ad42"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.169550Z",
     "start_time": "2025-09-11T14:55:24.757507Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(not 1)  # False\n",
    "print(not '')  # True"
   ],
   "id": "19c084a212797aa6",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "execution_count": 26
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "#### 逻辑与 and\n",
    "\n",
    "- 二元运算符，表示“并且”，要求二个操作数均为 True 时，结果为 True，其它情况结果均为 False。\n",
    "- 逻辑与的真值表如下：\n",
    "\n",
    "| 操作数A | 操作数B | A and B |\n",
    "| ------- | ------- | ------- |\n",
    "| True    | True    | True    |\n",
    "| True    | False   | False   |\n",
    "| False   | True    | False   |\n",
    "| False   | False   | False   |\n",
    "\n",
    "- 短路运算规则：如果已经判定第一个操作数是 False，则不再判断第二个操作数。\n",
    "- 逻辑与运算的返回结果：最早确定表达式值的操作数。即，表达式 a and b 的返回值，如果 a 是 False，则返回 a，如果 a 是 True，则返回 b。"
   ],
   "id": "e8c94a2bca8abffc"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.171241300Z",
     "start_time": "2025-10-14T03:57:44.888971Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(6 and 'lucky')  # 'lucky'\n",
    "print(0 and '')  # 0"
   ],
   "id": "fa971953a987de3b",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "lucky\n",
      "0\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 复合赋值运算\n",
    "\n",
    "- 注意复合赋值运算符是一个整体，其中的二个符号中间不可插入空格\n",
    "- 下面示例中设初始值 a=10\n",
    "\n",
    "| 运算符 | 描述                | 举例                                  |\n",
    "| ------ | ------------------- | ------------------------------------- |\n",
    "| +=     | a+=b，即a=a+b       | a+=1，结果a的值变为11                 |\n",
    "| -=     | a-=b，即a=a-b       | a-=1，结果a的值变为9                  |\n",
    "| *=     | a\\*=b，即a=a\\*b     | a*=3，结果a的值变为30                 |\n",
    "| /=     | a/=b，即a=a/b       | a/=3，结果a的值变为3.3333333333333335 |\n",
    "| //=    | a//=b，即a=a//b     | a//=3，结果a的值变为3                 |\n",
    "| %=     | a%=b，即a=a%b       | a%=3，结果a的值变为1                  |\n",
    "| **=    | a\\*\\*=b，即a=a\\*\\*b | a**=2，结果a的值变为100               |\n",
    "\n",
    "## 运算符优先级\n",
    "\n",
    "- 下表描述了常用运算符的优先级，从上向下优先级为由高到低。\n",
    "- 必要时，尽量使用小括号使代码逻辑更清晰。\n",
    "\n",
    "| 运算符                   | 描述                                               | 操作数个数 |\n",
    "| ------------------------ | -------------------------------------------------- | ---------- |\n",
    "| **                       | 幂运算符                                           | 二元       |\n",
    "| + -                      | 一元运算符：一元加、一元减                         | 一元       |\n",
    "| * / // %                 | 乘除运算符：乘法、算术除法、地板除法、取模（取余） | 二元       |\n",
    "| + -                      | 加减运算符：二元加、二元减                         | 二元       |\n",
    "| <= < > >= == !=          | 比较运算符                                         | 二元       |\n",
    "| not                      | 逻辑非                                             | 一元       |\n",
    "| and                      | 逻辑与                                             | 二元       |\n",
    "| or                       | 逻辑或                                             | 二元       |\n",
    "| = += -= *= /= //= %= **= | 赋值运算符                                         | 二元       |\n",
    "\n",
    "## 注释\n",
    "\n",
    "### 注释的作用\n",
    "\n",
    "- 注释（Comments）用来向用户提示或解释某些代码的作用和功能，它可以出现在代码中的任何位置。解释器在执行代码时会忽略注释，不做任何处理，就好像它不存在一样。\n",
    "- 在调试（Debug）程序的过程中，注释还可以用来临时移除无用的代码。如果觉得某段代码可能有问题，可以先把这段代码注释起来，让 Python 解释器忽略这段代码，然后再运行调试。\n",
    "- 注释的最大作用是提高程序的可读性，没有注释的程序简直就是天书。\n",
    "- 虽然良好的代码可以自成文挡，为了让今后阅读这段代码的人，能够理解你的思路。或者一段时间以后，你自己也不清楚当时写这段代码的目的了。所以程序应该书写适量的注释。\n",
    "- 一般情况下，合理的代码注释应该占源代码的 1/3 左右。\n",
    "\n",
    "### 单行注释\n",
    "\n",
    "- Python 使用 # 号实现单行注释。\\# 注释可以在一行中从头开始，也可以从中间开始。\n",
    "- 从 \\# 开始，直到这行结束为止的所有内容都是注释。Python 解释器遇到 `#`时，会忽略它后面的整行内容。"
   ],
   "id": "1be74de11f63c81e"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "#使用print输出字符串\n",
    "print(\"Hello World!\")\n",
    "print(\"Python is fun.\")\n",
    "\n",
    "#使用 print输出数字\n",
    "print(100)\n",
    "print(3 + 100 * 2)\n",
    "print((3 + 100) * 2)\n",
    "\n",
    "print(\"Hello World!\")  #输出Python欢迎信息\n",
    "print(36.7 * 14.5)  #输出乘积\n",
    "print(100 % 7)  #输出余数"
   ],
   "id": "68243604fe94f597"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "### 多行注释\n",
    "\n",
    "- 多行注释指的是一次性注释程序中多行的内容（包含一行）。\n",
    "- Python 使用三个连续的单引号'''或者三个连续的双引号\"\"\"注释多行内容。\n",
    "- 多行注释通常用来为 Python 文件、模块、类或者函数等添加版权或者功能描述信息。"
   ],
   "id": "eb0f88da47df78cc"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "'''\n",
    "使用 3 个单引号分别作为注释的开头和结尾\n",
    "可以一次性注释多行内容\n",
    "这里面的内容全部是注释内容\n",
    "'''\n",
    "\n",
    "\"\"\"\n",
    "使用 3 个双引号分别作为注释的开头和结尾\n",
    "可以一次性注释多行内容\n",
    "这里面的内容全部是注释内容\n",
    "\"\"\"\n"
   ],
   "id": "7b574f2f9ddd08f4"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- Python 多行注释不支持嵌套，所以下面的写法是错误的："
   ],
   "id": "e79e8954b211e603"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "'''\n",
    "外层注释\n",
    "    '''\n",
    "内层注释\n",
    "'''\n",
    "'''"
   ],
   "id": "d84d437a1d51e5e5"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- 不管是多行注释还是单行注释，当注释符作为字符串的一部分出现时，就不能再将它们视为注释标记，而应该看做正常代码的一部分。"
   ],
   "id": "b71e7cf87e611e37"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-24T04:49:59.180677Z",
     "start_time": "2025-09-11T14:59:55.068771Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print('''Hello,World!''')\n",
    "print(\"\"\"Python is fun.\"\"\")\n",
    "print(\"#是单行注释的开始\")"
   ],
   "id": "e162461ad24e643f",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello,World!\n",
      "Python is fun.\n",
      "#是单行注释的开始\n"
     ]
    }
   ],
   "execution_count": 28
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
